package ru.pb.auth.managers;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;

import ru.pb.auth.dao.IpsDAO;
import ru.pb.auth.model.IP;
import ru.pb.global.dao.DAOManager;
import ru.pb.global.network.utils.NetworkUtil;

/**
 * @author Felixx
 */
public class IPManager
{
	private static final Logger _log = Logger.getLogger(IPManager.class);
	private static final IpsDAO _dao = DAOManager.getDAOImpl(IpsDAO.class);
	private static IPManager _instance;

	private final Map<String, IP> _ips = new ConcurrentHashMap<String, IP>(); // список айпишников

	public static IPManager getInstance()
	{
		if(_instance == null)
			_instance = new IPManager();
		return _instance;
	}

	private IPManager()
	{
		load();

		updateStatusesIP();

		int whiteSize = 0;
		int blackSize = 0;
		for(IP ip : _ips.values())
		{
			if(ip.isWhite())
			{
				whiteSize++;
			}
			else
			{
				blackSize++;
			}
		}

		_log.info("loaded " + blackSize + " black ip's/masks");
		_log.info("loaded " + whiteSize + " white ip's/masks");
	}

	private void load()
	{
		List<IP> ips = _dao.select();
		for(IP ip : ips)
		{
			info(ip);
			add(ip);
		}
	}

	private void add(IP ip)
	{
		_ips.put(ip.getIp(), ip);
	}

	public void info(IP ip)
	{
		int allSeconds = ip.getEndTime() == -1 ? -1 : (int) ((ip.getEndTime() - (System.currentTimeMillis())) / 1000);

		if(allSeconds > 0)
		{
			int minutes = allSeconds / 60;
			int hour = minutes / 60;
			int seconds = allSeconds - (minutes * 60);
			String info = String.format("ip/mask is deleted after %d:%d:%d(hour:minute:second).", hour, minutes, seconds);
			_log.info(info);
		}
	}

	public void addToListIp(String ips, String admin, int timeInMinutes, boolean white)
	{
		final long current = System.currentTimeMillis();
		IP ip = new IP(ips, admin, current, current + timeInMinutes * 60000, white);

		info(ip);

		// TODO: Логи

		_dao.insert(ip);

		add(ip);
	}

	public void deleteIPFromList(IP ip, String admin)
	{
		_ips.remove(ip.getIp());

		_dao.delete(ip.getIp());

		// TODO: Логи
	}

	/**
	 * проверяет айпи, если тру то айпи забанена.
	 * если фелс то можно играть
	 * 
	 * @param ip
	 *            айпи
	 * @return можно ли?
	 */
	public boolean checkIP(String ip)
	{
		updateStatusesIP(); // обновляем айпишникы по времени

		return !isInList(ip, true) && isInList(ip, false);
	}

	public void updateStatusesIP()
	{
		for(IP ip : _ips.values())
		{
			if((ip.getEndTime() < System.currentTimeMillis()) && ip.getEndTime() > 0) // если вишло время удаляем с базы
			{
				deleteIPFromList(ip, "IPManager");

				_log.info("delete from black_ips ip/mask " + ip.getIp());
			}
		}
	}

	public boolean isInList(String ip, boolean white)
	{
		for(IP ipT : _ips.values())
		{
			if(NetworkUtil.checkIPMatching(ipT.getIp(), ip) && ipT.isWhite() == white)
				return true;
		}
		return false;
	}
}